package com.open.yujiakj.common.utils.secret;



import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.symmetric.SymmetricAlgorithm;
import cn.hutool.crypto.symmetric.SymmetricCrypto;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.apache.xmlbeans.impl.util.Base64;

import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;
import java.io.File;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;

@Slf4j
public class AesExUtil {
    private static final String AES = "AES";
    public static String DEFAULT_CHARSET = "UTF-8";

    /**
     * 加密字符串
     *
     * @param source
     * @param key
     * @return
     * @throws Exception
     */
    public static String encrypt(String source, String key) throws Exception {
        byte[] bt = encrypt(source.getBytes(DEFAULT_CHARSET), key.getBytes(DEFAULT_CHARSET));
        return new String(Base64.encode(bt), DEFAULT_CHARSET);
    }

    /**
     * 解密字符串
     *
     * @param source
     * @param key
     * @return
     * @throws Exception
     */
    public static String decrypt(String source, String key) throws Exception {
        byte[] bt = decrypt(Base64.decode(source.getBytes(DEFAULT_CHARSET)), key.getBytes(DEFAULT_CHARSET));
        return new String(bt, DEFAULT_CHARSET);
    }

    /**
     * 加密文件
     *
     * @param sourceFile
     * @param destFile
     * @param key
     * @throws Exception
     */
    public static void encrypt(File sourceFile, File destFile, String key) throws Exception {
        byte[] content = FileUtils.readFileToByteArray(sourceFile);
        byte[] des = encrypt(content, key.getBytes(DEFAULT_CHARSET));
        FileUtils.writeByteArrayToFile(destFile, des);
    }

    /**
     * 解密文件
     *
     * @param sourceFile
     * @param destFile
     * @param key
     * @throws Exception
     */
    public static void decrypt(File sourceFile, File destFile, String key) throws Exception {
        byte[] content = FileUtils.readFileToByteArray(sourceFile);
        byte[] des = decrypt(content, key.getBytes(DEFAULT_CHARSET));
        FileUtils.writeByteArrayToFile(destFile, des);
    }

    /**
     * 加密
     *
     * @param content
     *            需要加密的内容
     * @param password
     *            加密密码
     * @return
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeyException
     * @throws NoSuchPaddingException
     * @throws BadPaddingException
     * @throws IllegalBlockSizeException
     * @throws UnsupportedEncodingException
     */
    public static byte[] encrypt(byte[] content, byte[] password)
            throws NoSuchAlgorithmException, InvalidKeyException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException {
        KeyGenerator kgen = KeyGenerator.getInstance(AES);
        kgen.init(128, new SecureRandom(password));
        SecretKey secretKey = kgen.generateKey();
        byte[] enCodeFormat = secretKey.getEncoded();
        SecretKeySpec key = new SecretKeySpec(enCodeFormat, AES);
        Cipher cipher = Cipher.getInstance(AES);// 创建密码器
        cipher.init(Cipher.ENCRYPT_MODE, key);// 初始化
        return cipher.doFinal(content);
    }

    /**
     * 解密
     *
     * @param content
     *            待解密内容
     * @param password
     *            解密密钥
     * @return
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeyException
     * @throws NoSuchPaddingException
     * @throws BadPaddingException
     * @throws IllegalBlockSizeException
     */
    public static byte[] decrypt(byte[] content, byte[] password) throws NoSuchAlgorithmException, InvalidKeyException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException {
        KeyGenerator kgen = KeyGenerator.getInstance(AES);
        kgen.init(128, new SecureRandom(password));
        SecretKey secretKey = kgen.generateKey();
        byte[] enCodeFormat = secretKey.getEncoded();
        SecretKeySpec key = new SecretKeySpec(enCodeFormat, AES);
        Cipher cipher = Cipher.getInstance(AES);// 创建密码器
        cipher.init(Cipher.DECRYPT_MODE, key);// 初始化
        return cipher.doFinal(content);
    }
    //    长度只能是16位，24位，32位
    private static final String defaultKey = "1234567891011123";

    public static String encryptBase64(String content,String key){
        try{
            byte[] byteKey = SecureUtil.generateKey(SymmetricAlgorithm.AES.getValue(),
                    key.getBytes()).getEncoded();
            SymmetricCrypto aes = SecureUtil.aes(byteKey);
            // 加密
            return aes.encryptBase64(content);
        }catch (Exception e){
            log.error(" 加密异常:{}",e.getMessage());
        }
        return null;
    }

    public static String decryptStr(String encryptString,String key){
        try{
            byte[] byteKey = SecureUtil.generateKey(SymmetricAlgorithm.AES.getValue(),
                    key.getBytes()).getEncoded();
            SymmetricCrypto aes = SecureUtil.aes(byteKey);
            //解密
            return aes.decryptStr(encryptString);
        }catch (Exception e){
            log.error(" 解密异常:{}",e.getMessage());
        }
        return null;
    }



    public static void main(String[] args) {
        // 16位自定义密码
        String key = "1234567891011123";
        String content = "明文";
        String encryptStr = encryptBase64(content,key);
        System.out.println(decryptStr(encryptStr,key));
    }
}
